package com.wx.file;

import org.junit.jupiter.api.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 节点流的联系
 * 节点流 可以称之为端点流
 * 是跟端点直接进行操作的
 * @author wangxun
 * @version 1.0
 * @description: 练习
 * @date 2021/1/25 5:30 下午
 */
public class EndPointStreamTest {
    @Test
    void FileReaderTest(){
        File file = new File("D://1.txt");
        System.out.println(file.getAbsolutePath());
        FileReader fileReader = null;
        try {
            fileReader = new FileReader(file);
            char[] chars = new char[6];
            int length = 0;
            while((length = fileReader.read(chars))!=-1){
                String s = new String(chars, 0, length);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileReader != null)
                    fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Test
    void FileWriterTest(){
        File file = new File("src/main/resources/I.txt");
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(file);
            fileWriter.write("I am writer");
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileWriter != null)
                    fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 为什么字符流不能读取二进制文件
     */
    @Test
    void binaryFileTest(){
        File file = new File("src/main/resources/binary");
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            byte[] bytes = new byte[] {48,49};
            fos.write(bytes);
            FileReader(file);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void FileReader(File file){
        FileReader fileReader = null;
        try {
            fileReader = new FileReader(file);
            char[] chars = new char[2];
            int length;
            while((length = fileReader.read(chars))!=-1){
                String s = new String(chars, 0, length);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileReader != null)
                    fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * char 类型 是否是 utf-16
     */
    @Test
    void charTest() throws IOException {

        String s = new String("中");
        byte[] bytes = s.getBytes();
        for (byte aByte : bytes) {
            // byte转化成二进制字符串
            System.out.println(Integer.toBinaryString((aByte & 0xFF) + 0x100).substring(1));
        }

        //System.in.read();
    }


    /**
     * 用字节流复制
     */

    void copyStreamTest(File src,File dist,int size) throws IOException {


        FileInputStream is = new FileInputStream(src);

        FileOutputStream os = new FileOutputStream(dist);

        byte[] bytes = new byte[size];

        int len;
        while((len=is.read(bytes))!=-1){
            os.write(bytes,0,len);
        }

        is.close();
        os.close();
    }


    /**
     * 用缓冲流复制
     */

    void copyBufferedTest(File src,File dist,int size) throws IOException {


        FileInputStream is = new FileInputStream(src);

        FileOutputStream os = new FileOutputStream(dist);

        BufferedInputStream bis = new BufferedInputStream(is);

        BufferedOutputStream bos = new BufferedOutputStream(os);



        byte[] bytes = new byte[size];
        int len;
        while((len=bis.read(bytes))!=-1){
            bos.write(bytes,0,len);
        }

        is.close();
        os.close();
    }


    /**
     * 比较节点流和缓冲流 copy 文件的速度
     */
    @Test
    void streamVsBufferedTest(){
        File src = new File("D:\\VM-OS\\CentOS-7-x86_64-DVD-2009.iso");
        File dist = new File("D:\\VM-OS\\1.iso");
        long start = System.currentTimeMillis();
        try {
            /**
             * 1024 time: 27663
             * 8192 time: 6382
             * 100*1024*1024 time: 4593
             * 3*1024*1024 time: 2615
             * 256*1024 time: 2405
             */
            copyStreamTest(src,dist,3*1024*1024);
            /**
             * time: 6209
             */
            /**
             * Buffered缓冲流，如果要读取的数据长度大于缓存区长度8*1024
             * 那么就用FileInputStream 去直接读取数据长度，就不对缓冲区进行填充
             * 如果要读取的长度小于缓冲区的长度，就把缓冲区的数据直接拷贝长度赋值给对应的数组
             * 每次缓冲区的数据不够此次要读取的长度，就会对缓冲区进行新的填充
             *
             * 重载的构造器可以自定义缓冲区的大小BufferedInputStream(InputStream in, int size)
             * 默认长度为8192字节
             */
           // copyBufferedTest(src,dist,12*1024);
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("time: "+(end-start));

    }
}
